import commonMixin from '../mixins/common.js'

import CM from '@/class/index.js'

// 每种类型的日期权重，决定列表的列数
const DATE_TYPES = {
  year: 1,
  month: 2,
  day: 3,
  hour: 4,
  min: 5
}

export default {
  name: 'cm-picker-lunar',
  mixins: [
    commonMixin
  ],
  props: {
    // 日期选择器的种类，year年 / month月 / day日 / hour小时 / min分钟
    type: {
      default: 'min',
      type: String,
      validator (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['year', 'month', 'day', 'hour', 'min'].indexOf(value) !== -1
      }
    },
    // 起始农历年, 默认1900年开始
    start: {
      default: 1900,
      type: [String, Number]
    },
    // 结束农历年, 默认2100年结束
    end: {
      default: 2100,
      type: [String, Number]
    },
    // 农历日期初始，索引数组
    values: {
      default () {
        return []
      },
      type: Array
    },
    // 选中框样式，只能传样式CSS字符串
    indicatorStyle: {
      type: String,
      default: 'background-color: rgba(0, 0, 0, 0.04);'
    }
  },
  computed: {
  },
  data () {
    return {
      // 真正决定视图内容的列表数据
      dataList: [],
      // 真正决定视图内容的选中索引集
      indexes: [],
      // 列表列数
      colNum: DATE_TYPES[this.type]
      /*
        没在data中定义，但是是重要的组件参数的
        startYear 起始年
        endYear 结束年
      */
    }
  },
  methods: {    
    // 选中数据改变是触发
    changeHandler (e) {
      if (!e.isSet) {
        // 原生change事件，要设置100ms间隔的锁，避免连续触发，影响性能
        // 因为uni-app的bug，picker-view放置在popup中会有初始化错乱的bug，导致连续错误地触发此事件
        if (this.changeLock) {
          return
        }
        this.changeLock = true
        clearTimeout(this.changeTimer)
        this.changeTimer = setTimeout(() => {
          this.changeLock = false
        }, 100)
      }
      
      let val = e.detail.value
      // 先更新数据集
      this.updateData(val)
      // 获取text集
      const valueText = val.map((des, index) => {
        if (!Array.isArray(this.dataList[index]) || this.dataList[index].length === 0) {
          return null
        }
        if (des < this.dataList[index].length) {
          return this.dataList[index][des].text
        }
        // 处理长度超标的情况，修正val值
        const fixed = this.dataList[index].length - 1
        val[index] = fixed
        return this.dataList[index][fixed].text
      })
      // 获取value集
      const valueList = val.map((des, index) => {
        if (!Array.isArray(this.dataList[index]) || this.dataList[index].length === 0) {
          return null
        }
        // 由于之前获取text集时已经修正过val值，所以这里不会再出现长度超标的情况
        return this.dataList[index][des].value
      })
      // 更新index数据
      this.indexes = val
      // 触发事件
      this.$emit('change', valueList, valueText, val)
    },
    
    // 设定数据集和选中值，可以用于手动初始化
    set (startYear, endYear, values = []) {
      // 初始化数据集
      this.setData(startYear, endYear)
      // 初始化选中值
      this.setValues(values)
    },
    
    // 设置数据集，并重置所有选中值为0
    setData (startYear, endYear) {
      // 初始化数据集和索引集
      this.dataList = []
      let indexes = []
      // 更新起止时间
      this.startYear = parseInt(startYear)
      this.endYear = parseInt(endYear) >= this.startYear ? parseInt(endYear) : this.startYear
      // 更新动态更新年的数据
      if (this.colNum >= DATE_TYPES.year) {
        const yearList = this.initNumCol(this.startYear, this.endYear)
        this.dataList.push(yearList)
        indexes.push(0)
      }
      // 动态更新月的数据
      if (this.colNum >= DATE_TYPES.month) {
        indexes.push(0)
        const monthData = CM.Date.getLunarMonths(this.startYear)
        const monthList = monthData.lunarMonths.map((month, index) => {
          return {
            text: month,
            value: monthData.lunarMonthsRulue[index]
          }
        })
        this.dataList.push(monthList)
        
        // 动态更新日的数据
        if (this.colNum >= DATE_TYPES.day) {
          indexes.push(0)
          const dayNum = monthData.lunarMonthsDays[0]
          const rulueStart = monthData.lunarMonthsRulue[0]
          let dayList = []
          for (let i = 0; i < dayNum; i++) {
            const obj = {
              text: CM.Date.config.LUNAR_DAY.list[i],
              value: rulueStart + i
            }
            dayList.push(obj)
          }
          this.dataList.push(dayList)
        }        
      }
      // 初始化时数据
      if (this.colNum >= DATE_TYPES.hour) {
        const hourList = this.initNumCol(0, 23)
        this.dataList.push(hourList)
        indexes.push(0)
      }
      // 初始化分数据
      if (this.colNum >= DATE_TYPES.min) {
        const minList = this.initNumCol(0, 59)
        this.dataList.push(minList)
        indexes.push(0)
      }
      this.indexes = indexes
    },
    
    // 更新数据集
    updateData (values = []) {
      if (typeof values[0] === 'number' && this.colNum >= DATE_TYPES.month) {
        // 年改变了，更新月的级联数据
        let yearIndex = values[0]
        if (yearIndex < 0) { yearIndex = 0 }
        if (yearIndex >= this.dataList[0].length) { yearIndex = this.dataList[0].length - 1 }
        const startYear = yearIndex + this.dataList[0][0].value
        const monthData = CM.Date.getLunarMonths(startYear)
        const monthList = monthData.lunarMonths.map((month, index) => {
          return {
            text: month,
            value: monthData.lunarMonthsRulue[index]
          }
        })
        this.$set(this.dataList, 1, monthList)
        
        if (typeof values[1] === 'number' && this.colNum >= DATE_TYPES.day) {
          // 月改变了，更新日的级联数据
          let monthIndex = values[1]
          if (monthIndex < 0) { monthIndex = 0 }
          if (monthIndex >= this.dataList[1].length) { monthIndex = this.dataList[1].length - 1 }
          const dayNum = monthData.lunarMonthsDays[monthIndex]
          const rulueStart = monthData.lunarMonthsRulue[monthIndex]
          let dayList = []
          for (let i = 0; i < dayNum; i++) {
            const obj = {
              text: CM.Date.config.LUNAR_DAY.list[i],
              value: rulueStart + i
            }
            dayList.push(obj)
          }
          this.$set(this.dataList, 2, dayList)
        }
      }
    },
    
    // 设定picker的值
    setValues (values = []) {
      values = this.fillValues(values)
      // 模拟onChange事件，并手动触发
      const event = {
        isSet: true,
        detail: {
          value: values
        }
      }
      this.changeHandler(event)
    },
    
    // 对长度不足的values对象进行补齐，对长度超过的values的对象进行截断
    fillValues (values = []) {
      let len = this.colNum
      const valuesLen = values.length
      if (valuesLen > len) {
        // 截断
        return values.slice(0, len)
      }
      // 补齐
      for (let i = 0; i < len - valuesLen; i++) {
        values.push(0)
      }
      return values
    },
    
    // 给定起始值数字与结束值数字，初始化某列
    initNumCol (start = 0, end = 0) {
      let list = []
      for (let i = start; i <= end; i++) {
        let obj = {
          text: i.toString(),
          value: i
        }
        list.push(obj)
      }
      return list
    },
  },
  created () {
    // 初始化
    this.set(this.start, this.end, this.values)
  }
}